import JJBaseRequest from './JJBaseRequest.js';
import { hexMD5, WxNotificationCenter } from '../thirdparty/index.js';
import { JJUtil, JJCrypt, JJLog } from '../util/index.js';
import { JJUrlConfigHelper, JJDeviceHelper } from '../bizUtil/index.js';
import JJLoginService from './../service/loginService/JJLoginService.js'
import APPConfig from './../resource/file/appConfig/JJAPPConfig.js';

const g_cacheIv = 'qwe123!@#'

export default class JJRequest extends JJBaseRequest {

    userCacheDirectory = 'JJService'
    
    identity = '';
    isEncryption = true;
    isSaveToDisk = false;
    parametersForSavedFileName = null;
    sensitiveDataForSavedFileName = null;

    constructor(identity, parameters, isEncryption, isSaveToDisk) {
        super()

        this.identity = identity;
        this.parameters = parameters;
        this.isEncryption = isEncryption;
        this.isSaveToDisk = isSaveToDisk;

        this.otherInfo.parameters = parameters

        if (JJLoginService.shareInstance().getIsUserDidOnline() && JJUtil.isNotNull(JJLoginService.shareInstance().getUserID())) {
            this.sensitiveDataForSavedFileName = JJLoginService.shareInstance().getUserID()
        }
    }

    getHostUrl() {
        const host = JJUrlConfigHelper.serverHostWithIdentity(this.identity)
        return host
    }

    getPathUrl() {
        const path = JJUrlConfigHelper.serverPathWithIdentity(this.identity)
        return path
    }

    requestParameter() {
        // todo
        let requestParameter = {}
        return requestParameter
    }

    postResponseNotification(isNetworkSuccess, isBusinessSuccess, response, errorObj, otherInfo) {
        let info = { isNetworkSuccess, isBusinessSuccess, response, errorObj, otherInfo }
        WxNotificationCenter.postNotificationName(this.identity, info)
    }

    requestCompleteFilter(response) {
        response = this.processResponse(response)

        this.otherInfo.responseData = response
        
        if (this.successForBusiness(response) && this.isSaveToDisk) {
            const oldObject = this.obtainCache()
            let newObject = this.filterSuccessCallBackValue(true, response)
            newObject = this.operation(oldObject, newObject)

            this.saveObjectToCache(newObject);
        }

        this.processAbnormalStatus(response)

        return Promise.resolve(response);
    }

    processResponse(response) {
        // todo 处理业务，如解密等
        return response
    }

    processAbnormalStatus(response) {
        // todo 
        if ('9999' == response.code) { // session超时
            JJLog.log('!!!!! login session 超时 !!!!' + ' url: ' + this.buildRequestUrl())
            JJLoginService.shareInstance().setIsUserDidOnline(false)
            JJLoginService.shareInstance().setSessionKey(null)
            WxNotificationCenter.postNotificationName(JJLoginService.JJLoginServiceNotificationNameLoginSessionTimeout, response)
        }
    }

    successForBusiness(response) {
        const success = ('0000' == response.code);
        return success;
    }

    operation(oldObj, newObj) {
        return newObj
    }

    getCacheKey() {
        let keyStr = ''

        if (JJUtil.isNull(this.sensitiveDataForSavedFileName)) {
            keyStr = keyStr + '_'
        } else {
            keyStr = keyStr + this.sensitiveDataForSavedFileName + '_'
        }

        keyStr = keyStr + this.identity + '_'

        if (JJUtil.isNull(this.parametersForSavedFileName)) {
            keyStr = keyStr + JSON.stringify(this.parameters)
        } else {
            keyStr = keyStr + JSON.stringify(this.parametersForSavedFileName)
        }

        if (JJUtil.isNotNull(this.userCacheDirectory)) {
            keyStr = this.userCacheDirectory + '/' + keyStr
        }

        let value = hexMD5(keyStr)
        if (APPConfig.isDebug) {
            value = keyStr
        }
        
        return value ? value : keyStr
    }

    obtainCache() {
        const keyStr = this.getCacheKey()
        const value = wx.getStorageSync(keyStr)
        if (JJUtil.isNull(value) || value.length <= 0) {
            return null
        }

        if (APPConfig.isDebug) {
            return value
        }

        const cryptKey = JJDeviceHelper.getDeviceNo()
        let decrypted = JJCrypt.aesDecrypt(value, cryptKey, g_cacheIv)
        try {
            const obj = JSON.parse(decrypted)
            return obj
        } catch (error) {
            return decrypted
        }
    }

    saveObjectToCache(obj) {
        if (JJUtil.isNull(obj)) {
            return
        }

        const keyStr = this.getCacheKey()
        const cryptKey = JJDeviceHelper.getDeviceNo()

        const encrypted = JJCrypt.aesEncrypt(obj, cryptKey, g_cacheIv)
        
        if (APPConfig.isDebug) {
            wx.setStorageSync(keyStr, obj)
        } else {
            wx.setStorageSync(keyStr, encrypted)
        }
    }

    removeCache() {
        const keyStr = this.getCacheKey();
        wx.removeStorageSync(keyStr);
    }

    // 获取通用参数
    __getCommonParameter() {
        // todo 
        let commonParam = {}
        return commonParam
    }

    toString() {
        const para = this.parameters
        let msg = '【Request】 url: ' + this.buildRequestUrl() + '; parameter: ' + JSON.stringify(para) + '; deviceNo: ' + JJDeviceHelper.getDeviceNo()
        return msg
    }
}
